package ua.yandex.collections;

public class MyArrayList implements MyList {
    
    static final int STANDARTSIZE = 10;
    
    private Object[] vector; //vector.length de-jure size
    private int capacity; //de-facto size
    
    MyArrayList() {
        capacity = 0;
        vector = new Object[STANDARTSIZE];
    }
    
    MyArrayList(int initCapacity) {
        capacity = 0;
        vector = new Object[initCapacity];
    }
    
    @Override
    public void add(Object e) {
        Object[] temp = {e};
        addAll(capacity, temp);
    }
    
    @Override
    public void add(int index, Object e) {
        Object[] temp = {e};
        addAll(index, temp);
    }
    
    @Override
    public void addAll(Object[] c) {
        addAll(capacity, c);
    }
    
    @Override
    public void addAll(int index, Object[] c) { //numeration from 0
        if (index > capacity || index < 0) {
            throw new IndexOutOfBoundsException();
        }
        ensureCapacity(c.length);
        System.arraycopy(vector, index, vector, c.length + index,
                capacity - index);
        System.arraycopy(c, 0, vector, index, c.length);
        capacity += c.length;
    }
    
    @Override
    public Object get(int index) {
        if (index >= capacity || index < 0) {
            throw new IndexOutOfBoundsException();
        }
        return vector[index];
    }
    
    @Override
    public Object remove(int index) {
        if (index >= capacity || index < 0) {
            throw new IndexOutOfBoundsException();
        }
        Object value = vector[index];
        System.arraycopy(vector, index + 1, vector, index, 
                capacity - index - 1);
        capacity--;
        return value;
    }
    
    @Override
    public void set(int index, Object e) {
        if (index >= capacity || index < 0) {
            throw new IndexOutOfBoundsException();
        }
        vector[index] = e;
    }
    
    @Override
    public int indexOf(Object o) {
        if(o != null) {
            for (int i = 0; i < capacity; i++) {
                if (vector[i].equals(o)) {
                    return i;
                }
            }
        }
        else {
            for (int i = 0; i < capacity; i++) {
                if (vector[i] == null) {
                    return i;
                }
            }
        }
        return -1;
    }
    
    @Override
    public int size() {
        return capacity;
    }
    
    @Override
    public void clear() {
        //vector = null;
        capacity = 0;
    }
    
    @Override
    public boolean isEmpty() {
        return capacity == 0;
    }
    
    @Override
    public Object[] toArray() {
        Object[] array = new Object[capacity];
        System.arraycopy(vector, 0, array, 0, capacity);
        return array;
    }
    
    @Override
    public String toString() {
        //String str = "";
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < capacity - 1; i++) {
            //str += vector[i].toString() + ", ";
            buf.append(vector[i].toString()).append(", ");
        }
        //str += vector[capacity - 1].toString();
        buf.append(vector[capacity - 1].toString());
        return buf.toString();
    }
    
    public void ensureCapacity(int minCapacity) {
        int temp = vector.length;
        if (temp - capacity >= minCapacity) {
            return;
        }
        temp += 1;
        do {
            temp *= 2;
        } while(temp - capacity < minCapacity);
        Object[] tempVector = new Object[temp];
        System.arraycopy(vector, 0, tempVector, 0, capacity);
        vector = tempVector;
    }
    
    public int vectorLength() {
        return vector.length;
    }
}